using System.Collections.Generic;
using UnityEngine;

public class CameraController : MonoBehaviour
{
	public class CameraPosition
	{
		public Quaternion rotation;

		public Vector3 position;

		public float fov;
	}

	public float fovLandscape;

	public float fovPortrait;

	private Transform transform_;

	public float normalSpeed = 10f;

	private float speed = 10f;

	private Vector3 targetPosition;

	private Quaternion targetRotation;

	private float targetFOV;

	private Transform followTransform;

	private Vector3 followStart;

	private float maxDistanceFromFollowStart;

	private float followDistance;

	private float followDelayTime;

	protected static List<CameraPosition> savedPositions = new List<CameraPosition>();

	public CameraBehaviour cameraBehaviour { get; protected set; }

	public Transform MyTransform
	{
		get
		{
			if (transform_ == null)
			{
				transform_ = base.transform;
			}
			return transform_;
		}
	}

	public Vector3 initialPosition { get; private set; }

	public Quaternion initialRotation { get; private set; }

	public float initialFOV { get; private set; }

	public static int SavePosition(CameraPosition pos)
	{
		savedPositions.Add(pos);
		return savedPositions.Count - 1;
	}

	public static CameraPosition SavedPosition(int savedPositionIndex)
	{
		return savedPositions[savedPositionIndex];
	}

	public void SetIdleTransform(Vector3 pos, Quaternion rot)
	{
		initialPosition = pos;
		initialRotation = rot;
	}

	private void Awake()
	{
		initialPosition = (targetPosition = MyTransform.position);
		initialRotation = (targetRotation = MyTransform.rotation);
		initialFOV = (targetFOV = GetComponent<Camera>().fieldOfView);
	}

	public void StartFollowing(Transform t, float delay)
	{
		StartFollowing(t, 1.5f, GetComponent<Camera>().fieldOfView, 100f, delay);
	}

	public void StartFollowing(Transform t, float distance, float targetFOV, float maxDistanceFromStart, float delay)
	{
		speed = normalSpeed;
		followDelayTime = delay;
		followStart = MyTransform.position;
		maxDistanceFromFollowStart = maxDistanceFromStart;
		this.targetFOV = targetFOV;
		followTransform = t;
		followDistance = distance;
	}

	public void SetCameraBehaviour(CameraBehaviour beh, bool instant = false)
	{
		cameraBehaviour = beh;
		cameraBehaviour.Start(GetComponent<Camera>(), instant);
	}

	public void StopFollowing()
	{
		followTransform = null;
		cameraBehaviour = null;
	}

	public void SetTargetInstant(int savedPositionIndex)
	{
		CameraPosition cameraPosition = savedPositions[savedPositionIndex];
		SetTargetInstant(cameraPosition.position, cameraPosition.rotation, cameraPosition.fov);
	}

	public void SetTargetInstant(Vector3 position, Quaternion rotation, float FOV)
	{
		StopFollowing();
		MyTransform.position = (targetPosition = position);
		MyTransform.rotation = (targetRotation = rotation);
		GetComponent<Camera>().fieldOfView = (targetFOV = FOV);
	}

	public void SetTarget(int savedPositionIndex)
	{
		CameraPosition cameraPosition = savedPositions[savedPositionIndex];
		SetTarget(cameraPosition.position, cameraPosition.rotation, cameraPosition.fov);
	}

	public void SetTarget(Vector3 position, Quaternion rotation, float FOV)
	{
		SetTarget(position, rotation, FOV, normalSpeed);
	}

	public void SetTarget(Vector3 position, Quaternion rotation, float FOV, float speed)
	{
		this.speed = speed;
		StopFollowing();
		targetFOV = FOV;
		targetPosition = position;
		targetRotation = rotation;
		cameraBehaviour = null;
	}

	private void UpdateFov()
	{
		float fieldOfView = GetComponent<Camera>().fieldOfView;
		fieldOfView = ((Screen.width <= Screen.height) ? fovPortrait : fovLandscape);
		GetComponent<Camera>().fieldOfView = Mathf.Lerp(GetComponent<Camera>().fieldOfView, fieldOfView, Time.deltaTime * speed);
	}

	private void Update()
	{
		if (cameraBehaviour != null)
		{
			cameraBehaviour.Update();
			return;
		}
		followDelayTime = Mathf.Max(0f, followDelayTime - Time.deltaTime);
		if (followTransform != null && followDelayTime == 0f && Vector3.Distance(MyTransform.position, followStart) < maxDistanceFromFollowStart)
		{
			float num = Vector3.Distance(followTransform.position, MyTransform.position);
			if (num > followDistance)
			{
				Vector3 vector = MyTransform.position - followTransform.position;
				targetPosition = followTransform.position + vector.normalized * followDistance;
			}
		}
		MyTransform.position = Vector3.Lerp(MyTransform.position, targetPosition, Time.deltaTime * speed);
		MyTransform.rotation = Quaternion.Lerp(MyTransform.rotation, targetRotation, Time.deltaTime * speed);
		GetComponent<Camera>().fieldOfView = Mathf.Lerp(GetComponent<Camera>().fieldOfView, targetFOV, Time.deltaTime * speed);
	}
}
